import axios from 'axios'

import type { ApiClient, Identifiable, PageData } from "../types/api";

import type {
    AxiosError,
    AxiosInstance,
    AxiosRequestConfig
} from 'axios'

abstract class BaseApiClient<T extends Identifiable> implements ApiClient<T>{
    protected readonly http: AxiosInstance
    protected readonly endpoint: string

    constructor(
        endpoint: string,
        config?: AxiosRequestConfig
    ) {
        this.endpoint = endpoint
        this.http = axios.create({
            baseURL: "http://localhost:8000/api/v1/",
            timeout: 5000,
            ...config
        })
    }

    findAll(params?: Record<string, any>): Promise<PageData<T>> {
        return this.http.get<PageData<T>>(this.endpoint, { params })
            .then(res => res.data)
            .catch((error: AxiosError) => {
                console.error('Failed to fetch:', error.message);
                throw error
            })
    }

    findById(id: number): Promise<T> {
        return this.http.get<T>(`${this.endpoint}/${id}`)
            .then(res => res.data)
            .catch((error: AxiosError) => {
                console.error('Failed to fetch:', error.message);
                throw error
            })
    }

    create(t: T): Promise<T> {
        return this.http.post<T>(this.endpoint, t)
            .then(res => res.data)
            .catch((error: AxiosError) => {
                console.error('Failed to create:', error.message);
                throw error
            })
    }

    delete(id: number | string): Promise<void> {
        return this.http.delete<void>(`${this.endpoint}/${id}`)
            .then(res => res.data)
            .catch((error: AxiosError) => {
                console.error('Failed to delete:', error.message);
                throw error
            })
    }

    update(t: T): Promise<T> {
        return this.http.put<T>(`${this.endpoint}/${t.id}`, t)
            .then(res => res.data)
            .catch((error: AxiosError) => {
                console.error('Failed to patch person:', error.message);
                throw error
            })
    }
}


export { BaseApiClient }